package br.com.edoc.controller.cadastro;



import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.primefaces.model.UploadedFile;






import br.com.edoc.controller.listagem.ListagemModuloController;

import br.com.edoc.entidade.File;
import br.com.edoc.entidade.Menu;
import br.com.edoc.entidade.MenuFolha;
import br.com.edoc.entidade.Modulo;
import br.com.edoc.excecoes.ExceptionApplication;
import br.com.edoc.excecoes.ExceptionValidador;
import br.com.edoc.gerentes.GerenteCadastro;
import br.com.edoc.gerentes.GerenteControleAcesso;

import br.com.edoc.ouvinte.OuvinteSelecao;





@ManagedBean(name="cadastroModulo")
@SessionScoped
public class CadastroModuloController extends CadastroPadraoController   {
	public UploadedFile getFile() {
		return file;
	}


	public void setFile(UploadedFile file) {
		this.file = file;
	}
	public void handleFileUpload(FileUploadEvent event) {
		FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		if(event.getFile()!=null && event.getFile().getContents().length>0){
			File file = new File();
			file.setName(event.getFile().getFileName());
			file.setStream(new ByteArrayInputStream(event.getFile().getContents()));
			
			try {
				getModulo().setImg(getAtendente().chamaGerenteUploadIcones().upload(file));
				System.out.print(getModulo().getImg());
			} catch (ExceptionApplication e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}


	/**
	 * 
	 */
	private static final long serialVersionUID = -6194093616795252479L;

	private Modulo modulo;

	private TreeNode root;  
	private List<Menu> listaMenus;

	private Menu mother;
	
	private HashMap<Integer, TreeNode> hashMapNo;
	
	 private UploadedFile file; 

	public void mostrarListagameModulos(){
		ListagemModuloController listagem =new ListagemModuloController();
		Modulo query = new Modulo();
		query.setNome(getModulo().getNome());
		listagem.setQuery(query);
		listagem.setOuvinteSelecao( new OuvinteSelecao() {

			@Override
			public void selecaoFeita(Object object) {
				// TODO Auto-generated method stub
				setModulo((Modulo) object);
				GerenteControleAcesso gc = getAtendente().chamaGerenteControleAcesso();
				setListaMenus(gc.findByMenusRaiz(getModulo()));
				setRoot(null);
			}
		});

		showInFormPopUp("diego");
	}
	public void removerMenu(){
		
		TreeNode tree=  getHashMapNo().get(getMother().getId());
		if(tree.getChildCount()>0){
			addAlertMessage("Este menu não pode ser removido devido existirem menus filhos relacionados");
		}else{
			GerenteControleAcesso gc = getAtendente().chamaGerenteControleAcesso();			
			try {
				gc.deletar(getMother());
				if(getMother().getMother()!=null){				
					tree.getParent().getChildren().remove(tree);
				
				}else{
					getRoot().getChildren().remove(tree);;
				}
				getHashMapNo().remove(getMother().getId());
			} catch (ExceptionApplication e) {
				// TODO Auto-generated catch block
				addErroMessage(e.getMessage());
			}			
		}
	}
	
	public void removerMenuFolha(){
		GerenteControleAcesso gc = getAtendente().chamaGerenteControleAcesso();
		try {
			TreeNode tree=  getHashMapNo().get(getMother().getId());
			tree.getParent().getChildren().remove(tree);
			getHashMapNo().remove(getMother().getId());
			gc.deletar(getMother());
			setMother(null);
			addInfoMessage("Menu excluído com sucesso");
		} catch (ExceptionApplication e) {
			// TODO Auto-generated catch block
			addErroMessage(e.getMessage());
		}
	}
	public void mostrarCadastroMenu(){
		
		CadastroMenuController cadastro =new CadastroMenuController(new Menu(getModulo(),getMother()));
		cadastro.setOuvinte(new OuvinteSelecao() {

			@Override
			public void selecaoFeita(Object object) {
				// TODO Auto-generated method stub
				Menu menu = (Menu) object;
				if(getHashMapNo().containsKey(menu.getId())){
					((DefaultTreeNode)getHashMapNo().get(menu.getId())).setData(menu);
				}else{
					if(menu.getMother()!=null)
						getHashMapNo().put(menu.getId(), new DefaultTreeNode(menu, ((DefaultTreeNode)getHashMapNo().get(menu.getMother().getId()))));
					else
						getHashMapNo().put(menu.getId(), new DefaultTreeNode(menu,root));
				}
				setManager(null);
				setMother(null);
			}
		});
		showInFormPopUp("cadMenu");
	}
	public void alterarMenu(){
		CadastroMenuController cadastro =new CadastroMenuController(getMother());
		cadastro.setOuvinte(new OuvinteSelecao() {

			@Override
			public void selecaoFeita(Object object) {
				// TODO Auto-generated method stub
				Menu menu = (Menu) object;
				if(getHashMapNo().containsKey(menu.getId())){
					((DefaultTreeNode)getHashMapNo().get(menu.getId())).setData(menu);
				}else{
					if(menu.getMother()!=null)
						getHashMapNo().put(menu.getId(), new DefaultTreeNode(menu, ((DefaultTreeNode)getHashMapNo().get(menu.getMother().getId()))));
					else
						getHashMapNo().put(menu.getId(), new DefaultTreeNode(menu,root));
				}
				setManager(null);
				setMother(null);
			}
		});
		showInFormPopUp("cadMenu");
	}
	
	public void mostrarCadastroMenuFolha(){
		CadastroMenuController cadastro =new CadastroMenuController(new MenuFolha(getModulo(),getMother()));
		cadastro.setOuvinte(new OuvinteSelecao() {

			@Override
			public void selecaoFeita(Object object) {
				// TODO Auto-generated method stub
				Menu menu = (Menu) object;
				if(getHashMapNo().containsKey(menu.getId())){
					((DefaultTreeNode)getHashMapNo().get(menu.getId())).setData(menu);
				}else{
					if(menu.getMother()!=null)
						getHashMapNo().put(menu.getId(), new DefaultTreeNode(menu, ((DefaultTreeNode)getHashMapNo().get(menu.getMother().getId()))));
					else
						getHashMapNo().put(menu.getId(), new DefaultTreeNode(menu,root));
				}
				setManager(null);
				setMother(null);
			}
		});
		showInFormPopUp("cadMenu");
	}


	@Override
	public void acaoInserir() {
		
		GerenteCadastro gc = getAtendente().chamaGerenteCadastro();
		try {
			
				
			gc.incluir(getModulo());
			addInfoMessage("Cadastro Realizado com sucesso");
		} catch (ExceptionApplication e) {
			// TODO Auto-generated catch block
			addErroMessage("Erro de Aplicação",e.getMessage());
		} catch (ExceptionValidador e) {
			// TODO Auto-generated catch block
			addErroMessage("Erro de Validação",e.getMessage());
		}
	}



	@Override
	public void acaoAlterar() {
		// TODO Auto-generated method stub
		GerenteCadastro gc = getAtendente().chamaGerenteCadastro();
		try {
			if(getFile()!=null && getFile().getContents().length>0){
				File file = new File();
				file.setName(getFile().getFileName());
				file.setStream(new ByteArrayInputStream(getFile().getContents()));
				
				try {
					getModulo().setImg(getAtendente().chamaGerenteUploadIcones().upload(file));
					System.out.print(getModulo().getImg());
				} catch (ExceptionApplication e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			gc.alterar(getModulo());
			addInfoMessage("Cadastro Realizado com sucesso");
		} catch (ExceptionApplication e) {
			// TODO Auto-generated catch block
			addErroMessage("Erro de Aplicação",e.getMessage());
		} catch (ExceptionValidador e) {
			// TODO Auto-generated catch block
			addErroMessage("Erro de Validação",e.getMessage());
		}
	}

	@Override
	public void acaoRemover() {
		// TODO Auto-generated method stub
		GerenteCadastro gc = getAtendente().chamaGerenteCadastro();
		try {
			gc.deletar(getModulo());
			addInfoMessage("Cadastro Realizado com sucesso");
		} catch (ExceptionApplication e) {
			// TODO Auto-generated catch block
			addErroMessage("Erro de Aplicação",e.getMessage());
		} 
	}
	public void acaoLimpar(){
		setListaMenus(null);
		setModulo(null);
		setRoot(null);
		setMother(null);
	}

	public Modulo getModulo() {
		if(modulo==null){
			modulo = new Modulo();
		}
		return modulo;
	}

	public void setModulo(Modulo modulo) {
		this.modulo = modulo;
	}
	public void preencheMenu(TreeNode pai,Menu menu){
		TreeNode no = new DefaultTreeNode(menu,pai);
		getHashMapNo().put(menu.getId(),no);
		if(!(menu instanceof MenuFolha)){
			GerenteControleAcesso ga = getAtendente().chamaGerenteControleAcesso();
			List<Menu> lista = ga.findByMenusFilhos(menu);
			if(lista != null){
				for(Menu currentMenu: lista){
					preencheMenu(no, currentMenu);
				}
			}
		}
	}

	public TreeNode getRoot() {
		if(root==null){
			root = new DefaultTreeNode("Root", null);
			for(Menu menu: getListaMenus()){
				
				preencheMenu(root,menu);
			}


			//			TreeNode node0 = new DefaultTreeNode("Node 0", root);  
			//			
			//			TreeNode node1 = new DefaultTreeNode("Node 1", root);  
			//			TreeNode node2 = new DefaultTreeNode("Node 2", root);  
			//
			//			TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);  
			//			TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);  
			//
			//			TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);  
			//			TreeNode node11 = new DefaultTreeNode("Node 1.1", node1);  
			//
			//			TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);  
			//			TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);  
			//			TreeNode node010 = new DefaultTreeNode("Node 0.1.0", node01);  
			//
			//			TreeNode node100 = new DefaultTreeNode("Node 1.0.0", node10);
		}
		return root;
	}

	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public void showPopfFalse(){
		setShowPopUp(Boolean.FALSE);
	}
	public List<Menu> getListaMenus() {
		if(listaMenus == null){
			listaMenus = new ArrayList<Menu>();
		}
		return listaMenus;
	}
	public void setListaMenus(List<Menu> listaMenus) {
		this.listaMenus = listaMenus;
	}
	public Menu getMother() {
		return mother;
	}
	public void setMother(Menu mother) {
		this.mother = mother;
	}


	public HashMap<Integer, TreeNode> getHashMapNo() {
		if(hashMapNo==null)
			hashMapNo= new HashMap<Integer, TreeNode>();
		return hashMapNo;
	}


	public void setHashMapNo(HashMap<Integer, TreeNode> hashMapNo) {
		this.hashMapNo = hashMapNo;
	}


}
